package org.example.handler;

import com.fasterxml.jackson.databind.ObjectMapper;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.websocketx.*;
import io.netty.util.CharsetUtil;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class HttpStompHandler extends SimpleChannelInboundHandler<Object> {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest) {
            // 处理HTTP请求
            handleHttpRequest(ctx, (FullHttpRequest) msg);
        } else if (msg instanceof WebSocketFrame) {
            // 处理WebSocket帧
            handleWebSocketFrame(ctx, (WebSocketFrame) msg);
        }
    }

    private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {
        // 判断请求方法
        if (request.method() == HttpMethod.GET) {
            handleGetRequest(ctx, request);
        } else if (request.method() == HttpMethod.POST) {
            handlePostRequest(ctx, request);
        }
    }

    private void handleGetRequest(ChannelHandlerContext ctx, FullHttpRequest request) {
        // 返回简单的JSON响应
        Map<String, String> responseData = new HashMap<>();
        responseData.put("message", "GET request received");

        String jsonResponse = serializeToJson(responseData);

        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                Unpooled.copiedBuffer(jsonResponse, CharsetUtil.UTF_8));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());

        ctx.writeAndFlush(response);
    }

    private void handlePostRequest(ChannelHandlerContext ctx, FullHttpRequest request) {
        // 读取并解析请求体
        String requestBody = request.content().toString(StandardCharsets.UTF_8);
        Map<String, Object> requestData = parseJson(requestBody);

        // 处理并返回JSON响应
        Map<String, String> responseData = new HashMap<>();
        responseData.put("message", "POST request received");
        responseData.put("requestData", requestData.toString());

        String jsonResponse = serializeToJson(responseData);

        FullHttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.OK,
                Unpooled.copiedBuffer(jsonResponse, CharsetUtil.UTF_8));
        response.headers().set(HttpHeaderNames.CONTENT_TYPE, "application/json; charset=UTF-8");
        response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());

        ctx.writeAndFlush(response);
    }

    private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
        // 如果是关闭帧
        if (frame instanceof CloseWebSocketFrame) {
            ctx.close();
            return;
        }

        // 如果是Ping帧
        if (frame instanceof PingWebSocketFrame) {
            ctx.write(new PongWebSocketFrame(frame.content().retain()));
            return;
        }

        // 只处理文本帧
        if (!(frame instanceof TextWebSocketFrame)) {
            throw new UnsupportedOperationException("Unsupported WebSocket frame");
        }

        // 处理文本消息
        String requestText = ((TextWebSocketFrame) frame).text();
        System.out.println("Received WebSocket message: " + requestText);

        // 响应消息
        TextWebSocketFrame response = new TextWebSocketFrame("Message received: " + requestText);
        ctx.channel().writeAndFlush(response);
    }

    private String serializeToJson(Object obj) {
        try {
            return objectMapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException("Error serializing object to JSON", e);
        }
    }

    private Map parseJson(String json) {
        try {
            return objectMapper.readValue(json, Map.class);
        } catch (Exception e) {
            throw new RuntimeException("Error parsing JSON", e);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }

}
